package com.xdl.flytest.util.job;


import com.xdl.flytest.bean.Task;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;

import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * @Auther: 80736
 * @Date: 2019/2/3 13:12
 * @Description:
 */

public class QuartzManager {

    private Scheduler scheduler;

    public void getRunningJob() throws SchedulerException {
        List<JobExecutionContext> jobContexts = scheduler.getCurrentlyExecutingJobs();
        for (JobExecutionContext context : jobContexts) {
            System.out.println("============================" + context.getTrigger().getJobKey().getName());
        }
    }


    /**
     * 获取所有job
     */
    public void getAllJobs() {
        try {
            for (String groupName : scheduler.getJobGroupNames()) {
                for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {
                    String jobName = jobKey.getName();
                    String jobGroup = jobKey.getGroup();
                    //get job's trigger
                    List<Trigger> triggers = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);
                    Date nextFireTime = triggers.get(0).getNextFireTime();
                    System.out.println("[jobName] : " + jobName + " [groupName] : "
                            + jobGroup + " - " + nextFireTime);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * job是否已经存在
     *
     * @param jobName
     * @param groupName
     * @return
     * @throws SchedulerException
     */
    public boolean exist(String jobName, String groupName) throws SchedulerException {
        JobDetail jobDetail = scheduler.getJobDetail(JobKey.jobKey(jobName, groupName));
        if (jobDetail != null) {
            return true;
        }

        return false;
    }


    /**
     * 添加一个job
     *
     * @param task     job info
     * @param jobClass job任务类
     * @return
     * @throws SchedulerException
     */
    public Date addJob(Task task, Class jobClass) throws SchedulerException {
        // 构建job信息
        JobDetail jobDetail = JobBuilder.newJob(jobClass)
                .withIdentity(task.getTaskName(), task.getJobGroup()).build();
        // 表达式调度构建器
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.getCronExpression());
        // 按cronExpression表达式构建trigger
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(task.getTaskName(), task.getJobGroup())
                .withSchedule(scheduleBuilder).build();
        // 放入参数，运行时的方法可以获取
        jobDetail.getJobDataMap().put(Task.JOB_PARAM, task);
        return scheduler.scheduleJob(jobDetail, trigger);

    }

    /**
     * @param jobName          任务名
     * @param jobGroupName     任务组名
     * @param triggerName      触发器名
     * @param triggerGroupName 触发器组名
     * @param jobClass         任务
     * @param cron             时间设置，参考quartz说明文档
     * @Description: 添加一个定时任务
     */

    @Deprecated
    public Date addJob(String jobName, String jobGroupName,
                       String triggerName, String triggerGroupName, Class jobClass, String cron) {
        try {
            // 任务名，任务组，任务执行类
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();

            // 触发器
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
            // 触发器名,触发器组
            triggerBuilder.withIdentity(triggerName, triggerGroupName);
            triggerBuilder.startNow();
            // 触发器时间设定
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
            // 创建Trigger对象
            CronTrigger trigger = (CronTrigger) triggerBuilder.build();


            scheduler.clear();
            // 调度容器设置JobDetail和Trigger
            Date date = scheduler.scheduleJob(jobDetail, trigger);

            // 启动
            if (!scheduler.isShutdown()) {
                scheduler.start();
            }

            return date;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 立即运行一次job
     *
     * @param task
     * @param jobClass
     * @param uuid
     * @throws SchedulerException
     */
    public void runningNow(Task task, Class jobClass, String uuid) throws SchedulerException {
        JobDetail job = JobBuilder.newJob(jobClass).withIdentity(uuid, uuid).build();
        //定义触发器
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity(uuid, uuid).startNow().withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(30).withRepeatCount(1)).build();
        scheduler.scheduleJob(job, trigger);
    }

    /**
     * @Description: 修改一个任务的触发时间
     */
    public void modifyJobTime(Task task) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(task.getTriggerName(), task.getTriggerGroup());
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            if (trigger == null) {
                return;
            }
            /** 方式一 ：调用 rescheduleJob 开始 */
                /*
                TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
                triggerBuilder.withIdentity(task.getTriggerName(), task.getTriggerGroup());
                triggerBuilder.startNow();
                triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(task.getCronExpression()));
                trigger = (CronTrigger) triggerBuilder.build();
                scheduler.rescheduleJob(triggerKey, trigger);
                */

            /** 方式二：先删除，然后在创建一个新的Job  */
            JobDetail jobDetail = scheduler.getJobDetail(JobKey.jobKey(task.getTaskName(), task.getJobGroup()));
            Class<? extends Job> jobClass = jobDetail.getJobClass();
            removeJob(task);
            addJob(task, jobClass);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 暂停一个任务
     *
     * @param task
     * @throws SchedulerException
     */
    public void pauseJob(Task task) throws SchedulerException {
        scheduler.pauseJob(JobKey.jobKey(task.getTaskName(), task.getJobGroup()));
    }

    /**
     * 重启一个任务
     *
     * @param task
     * @throws SchedulerException
     */
    public void resumeJob(Task task) throws SchedulerException {
        scheduler.resumeJob(JobKey.jobKey(task.getTaskName(), task.getJobGroup()));
    }

    /**
     * 打印内存中所有job
     *
     * @throws SchedulerException
     */
    public void printRamJob() throws SchedulerException {
        Set<TriggerKey> triggerKeys = scheduler.getTriggerKeys(GroupMatcher.anyTriggerGroup());
        for (TriggerKey tKey : triggerKeys) {
            CronTrigger t = (CronTrigger) scheduler.getTrigger(tKey);
            System.out.println("Trigger details: " + t.getJobKey().getName() + ", " + t.getJobKey().getGroup()
                    + ", " + scheduler.getTriggerState(tKey) + ", " + t.getFinalFireTime() + ", "
                    + t.getCronExpression());
        }
    }

    /**
     * @Description: 移除一个任务
     */
    public void removeJob(Task task) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(task.getTriggerName(), task.getTriggerGroup());
            scheduler.pauseTrigger(triggerKey);// 停止触发器
            scheduler.unscheduleJob(triggerKey);// 移除触发器
            scheduler.deleteJob(JobKey.jobKey(task.getTaskName(), task.getJobGroup()));// 删除任务
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description:启动所有定时任务
     */
    public void startJobs() {
        try {
            scheduler.start();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description:关闭所有定时任务
     */
    public void shutdownJobs() {
        try {
            if (!scheduler.isShutdown()) {
                scheduler.shutdown();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public Scheduler getScheduler() {
        return scheduler;
    }

    public void setScheduler(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

}
